import bibtexparser
from bibtexparser.bparser import BibTexParser
from bibtexparser.customization import convert_to_unicode
import re


class BibEntry:
    """表示BibTeX中的单个条目"""

    def __init__(self, entry_dict):
        self.entry_dict = entry_dict
        self.entry_type = entry_dict.get('ENTRYTYPE', '')
        self.entry_id = entry_dict.get('ID', '')

    def format_authors(self):
        """按照GB/T 7714-2015格式化作者列表"""
        if 'author' not in self.entry_dict:
            return ''

        authors = self.entry_dict['author'].split(' and ')
        formatted_authors = []

        for author in authors:
            # 检查是否是中文作者
            is_chinese = any('\u4e00' <= char <= '\u9fff' for char in author)

            if is_chinese:  # 中文作者不做特殊处理
                formatted_name = author.strip()
            elif ',' in author:  # 西方作者格式为"姓, 名"
                last_name, first_name = author.split(',', 1)
                first_initials = ''.join(name.strip()[0] for name in first_name.strip().split() if name.strip())
                formatted_name = f"{last_name.strip()} {first_initials}"
            else:  # 西方作者格式为"名 姓"
                parts = author.strip().split()
                if len(parts) > 1:
                    last_name = parts[-1]
                    first_names = parts[:-1]
                    first_initials = ''.join(name[0] for name in first_names if name)
                    formatted_name = f"{last_name} {first_initials}"
                else:
                    formatted_name = author.strip()

            formatted_authors.append(formatted_name)

        return ' , '.join(formatted_authors)

    def get_title(self):
        """获取格式化后的标题"""
        title = self.entry_dict.get('title', '')
        # 移除BibTeX中的花括号
        title = re.sub(r'{|}', '', title)

        # 确保非中文标题首字母大写
        if title and not any('\u4e00' <= char <= '\u9fff' for char in title):
            title = title[0].upper() + title[1:]

        return title

    def get_type_mark(self):
        """根据条目类型获取GB/T 7714-2015文献类型标记"""
        type_marks = {
            'article': 'J',  # 期刊论文
            'book': 'M',  # 专著
            'inbook': 'M',  # 书籍的一部分
            'incollection': 'M',  # 文集中的一篇
            'inproceedings': 'C',  # 会议论文
            'proceedings': 'C',  # 会议文集
            'conference': 'C',  # 会议
            'thesis': 'D',  # 学位论文
            'mastersthesis': 'D',  # 硕士论文
            'phdthesis': 'D',  # 博士论文
            'techreport': 'R',  # 技术报告
            'manual': 'M',  # 手册
            'misc': 'Z',  # 其他
        }

        return type_marks.get(self.entry_type.lower(), 'J')

    def to_bibitem(self):
        """将BibTeX条目转换为符合GB/T 7714-2015国标的bibitem格式"""
        authors = self.format_authors()
        title = self.get_title()
        year = self.entry_dict.get('year', '')
        type_mark = self.get_type_mark()

        bibitem = f"\\bibitem{{{self.entry_id}}}\n"
        bibitem += f"{authors}.{title}[{type_mark}]. {year}"

        if 'doi' in self.entry_dict:
            bibitem += f".DOI:{self.entry_dict['doi']}"

        bibitem += "."

        return bibitem


class BibManager:
    """管理BibTeX文件并提供转换功能的类"""

    def __init__(self, file_path):
        self.file_path = file_path
        self.entries = []
        self.load_bib_file()

    def load_bib_file(self):
        """加载并解析BibTeX文件"""
        try:
            with open(self.file_path, 'r', encoding='utf-8') as bibtex_file:
                parser = BibTexParser()
                parser.customization = convert_to_unicode
                bib_database = bibtexparser.load(bibtex_file, parser=parser)

            for entry in bib_database.entries:
                self.entries.append(BibEntry(entry))
        except Exception as e:
            print(f"加载BibTeX文件时出错: {e}")

    def get_entry_by_id(self, entry_id):
        """根据ID获取特定条目"""
        for entry in self.entries:
            if entry.entry_id == entry_id:
                return entry
        return None

    def get_all_entries(self):
        """获取所有条目"""
        return self.entries

    def convert_all_to_bibitem(self):
        """将所有条目转换为bibitem格式"""
        return [entry.to_bibitem() for entry in self.entries]

    def save_bibitems(self, output_file):
        """将所有bibitem保存到文件"""
        bibitems = self.convert_all_to_bibitem()
        try:
            with open(output_file, 'w', encoding='utf-8') as f:
                for bibitem in bibitems:
                    f.write(f"{bibitem}\n\n")
            print(f"已保存{len(bibitems)}个bibitem条目到{output_file}")
        except Exception as e:
            print(f"保存到文件时出错: {e}")